import sys
import numpy as np
import pandas as pd


class Solution:
    # 定义变量
    def __init__(self):
        self.row_sum = []#行之和
        self.col_sum = []#列之和
        self.lenth = []#单位数
        self.diff = []#净分化距离列表
        self.result = []#储存结果

    # 获取矩阵
    def get_martix(self):
        self.mat = pd.read_csv('tree.csv', index_col=0)
        # self.mat.index = []
        # self.mat.columns = []
        self.mat.index = self.mat.index.astype(str)# 获取列索引
        self.mat.columns = self.mat.columns.astype(str)# 获取行索引
        for j in self.mat.columns:#注意这两个循环的前后关系，为保证后续顺利遍历下三角，标准顺序应该为A开头(以此矩阵为例)
            if (j not in self.lenth):
                self.lenth.append(j)
        for i in self.mat.index:
            if (i not in self.lenth):
                self.lenth.append(i)
        print(self.lenth)
        # print(self.mat.index ,self.mat.columns)
        print(self.mat)

    # 净分化距离
    def Differentiation_index(self):
        self.row_sum = self.mat.sum(axis = 1)#行求和
        self.col_sum = self.mat.sum(axis = 0)#列求和
        # self.lenth = list(set(self.mat.index.astype('str') + self.mat.columns.astype('str')))
        # print(self.mat.index.astype('list') + self.mat.columns.astype('list'))
        # print(self.lenth)
        # sys.exit(0)
        # self.lenth = len(self.row_sum) + 1#物种数
        col = []
        row = []
        for i in self.col_sum:
            col.append(i)
        for i in self.row_sum:
            row.append(i)
        # print(row,col,'@@@@@@@@@')
        col.append(0)#列表延长
        row.insert(0,0)#列表延长
        # print(row,col)
        for i in range(len(self.lenth)):
            # print(loc[i],"##############")
            # print(row[i-1])
            # print(loc[i] + row[i-1])
            self.diff.append(col[i] + row[i])
        print(self.diff)
        # print(self.mat.sum(axis = 1))#行求和
        # print(self.mat.sum(axis = 0))#列求和
        # print(self.rows[0],self.cols[0])

    # 修正矩阵
    def Correction_matrix(self):
        cor = self.mat.copy()# 这种矩阵的索引为表头
        for x in range(1,len(self.lenth)):#遍历下三角
            i = self.lenth[x]
            for y in range(x):
                j = self.lenth[y]
                # print(i,j)
                # print(cor.loc[i,j])
                cor.loc[i,j] = cor.loc[i,j] - ((self.diff[self.lenth.index(i)] + self.diff[self.lenth.index(j)])/((len(self.lenth)-2)*1.00000))
        print(cor)
        i,j = cor.stack().idxmin()#在矩阵最小值集合中选取第一个
        # print(cor.stack().idxmin())
        print(i,j)
        self.result.append([i,j])
        return i,j

    # 抽象新物种
    def Abstract_new_species(self,i,j,u):# 抽象新物种
        sj = (self.mat.loc[i,j] / 2) + ((self.diff[self.lenth.index(j)] - self.diff[self.lenth.index(i)]) / (2 *(len(self.lenth) - 2)))#计算S(AU)
        si = self.mat.loc[i,j] - sj
        print(sj,si)
        matrix = self.mat.copy()
        # print(matrix,'########')
        print(i,j)
        # print(self.mat.columns,self.mat.index)
        if i in self.mat.columns:
            matrix = matrix.drop(labels = i, axis = 1)#删除列
        if j in self.mat.columns:
            matrix = matrix.drop(labels = j, axis = 1)
        if i in self.mat.index:
            matrix = matrix.drop(labels = i, axis = 0)#删除行
        if j in self.mat.index:
            matrix = matrix.drop(labels = j, axis = 0)
        # print(matrix)
        self.lenth.remove(i)#物种列表减少
        self.lenth.remove(j)
        self.lenth.insert(0,u)
        # print(self.lenth)
        matrix = matrix.loc[:, matrix.sum(axis=0) != 0]#删除全0行列
        matrix = matrix.loc[matrix.sum(axis=1) != 0, :]
        inde = []#全0列表
        change = []#行序交换
        for x in range(len(self.lenth) - 1):#添加行列的元素默认值为0
            inde.append(0)
        print(inde)
        matrix.loc[self.lenth[1]] = inde[: -1]
        for x in range(1,len(inde) + 1):
            change.append(x)
        for x in range(len(change)-1):##构造[2,3,4,1] 移动
            change.insert(0,change.pop())
        # print(change)
        matrix['change']=change
        matrix=matrix.sort_values(by='change')
        matrix.drop(columns='change',inplace=True)
        matrix.insert(0,u,inde)
        print(matrix)
        for x in range(1,len(self.lenth)):
            # print(self.mat.loc[self.lenth[x],j] + self.mat.loc[self.lenth[x],i] - (self.mat.loc[i,j] / (2 * 1.00000)))
            matrix.loc[self.lenth[x],u] = self.mat.loc[self.lenth[x],j] + self.mat.loc[self.lenth[x],i] - (self.mat.loc[i,j] / (2 * 1.00000))
        print(matrix)






tree = Solution()
tree.get_martix()
tree.Differentiation_index()
i,j = tree.Correction_matrix()
# for x in range(1,len(tree.lenth)):#抽象物种
#     u = ''
#     u = "u"+str(x)
#     print(u)
u="u1"
tree.Abstract_new_species(i,j,u)
print(tree.result)